//
//  ZXEmptyViewConfig.m
//  LKNetworkingDemo
//
//  Created by LIUKUN-PC on 16/8/24.
//  Copyright © 2016年 liukun. All rights reserved.
//

#import "LKEmptyViewConfig.h"
#import "UIImage+GIF.h"
#import "MJRefresh.h"
#import <objc/runtime.h>

static const CGFloat kEmptyViewMinHeight = 200;

@interface LKEmptyViewConfig () <DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, weak) UIScrollView *scrollView;

@property (nonatomic, assign) BOOL isNormalView;

/** 是否在加载，与MJRefresh的refresh状态配合使用 */
@property (nonatomic, assign) BOOL isLoading;

/** 是否加载过 */
@property (nonatomic, assign) BOOL isLoaded;

@end

@implementation LKEmptyViewConfig

#pragma mark - API

+ (instancetype)setupEmptyViewConfigForView:(UIView *)view {
    LKEmptyViewConfig *config = [[LKEmptyViewConfig alloc] init];
    [view.superview setNeedsLayout];
    [view.superview layoutIfNeeded];
    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)];
    tableView.tableFooterView = [[UIView alloc] init];
    config.scrollView = tableView;
    tableView.delegate = config;
    tableView.dataSource = config;
    config.isNormalView = YES;
    config.hidden = YES;
    [view addSubview:tableView];
    return config;
}


+ (instancetype)setupEmptyViewConfigForTableView:(UITableView *)tableView {
    LKEmptyViewConfig *config = [[LKEmptyViewConfig alloc] init];
    config.scrollView = tableView;
    if (!tableView.tableFooterView) {
        tableView.tableFooterView = [[UIView alloc] init];
    }
    config.isNormalView = NO;
    [config addObserver];
    
    return config;
}

+ (instancetype)setupEmptyViewConfigForCollectionView:(UICollectionView *)collectionView {
    LKEmptyViewConfig *config = [[LKEmptyViewConfig alloc] init];
    config.scrollView = collectionView;
    config.isNormalView = NO;
    [config addObserver];
    return config;
}

#pragma mark - KVO 监控state

- (void)addObserver {
    
//    NSKeyValueObservingOptionNew 把更改之前的值提供给处理方法
//    
//    NSKeyValueObservingOptionOld 把更改之后的值提供给处理方法
//    
//    NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法，一旦注册，立马就会调用一次。通常它会带有新值，而不会带有旧值。
//    
//    NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。
    
    /*
     NSKeyValueObservingOptionNew：change字典包括改变后的值
     NSKeyValueObservingOptionOld:   change字典包括改变前的值
     NSKeyValueObservingOptionInitial:注册后立刻触发KVO通知
     NSKeyValueObservingOptionPrior:值改变前是否也要通知（这个key决定了是否在改变前改变后通知两次）
     */
    
    __weak typeof(self) weakSelf = self;
    
    if (self.scrollView.mj_header) {
        
        [self.scrollView.mj_header addObserverForKeyPath:@"state" block:^(__weak id obj, id oldValue, id newValue) {
            weakSelf.isLoading = weakSelf.scrollView.mj_header.state == MJRefreshStateRefreshing;
            
        }];

    }
    
    if (self.scrollView.mj_footer) {
        
        [self.scrollView.mj_footer addObserverForKeyPath:@"state" block:^(__weak id obj, id oldValue, id newValue) {
            weakSelf.isLoading = weakSelf.scrollView.mj_footer.state == MJRefreshStateRefreshing;

        }];
    }
    
}

- (void)setIsLoading:(BOOL)isLoading {
    if (_isLoading == isLoading) {
        return;
    }
    _isLoading = isLoading;
    
    if (_isLoading && !self.isLoaded) {
        self.isLoaded = YES;
    }
    
    [self.scrollView reloadEmptyDataSet];
}



#pragma mark - Getter & Setter

- (void)setScrollView:(UIScrollView *)scrollView {
    _scrollView = scrollView;
    _scrollView.emptyDataSetDelegate = self;
    _scrollView.emptyDataSetSource = self;
    _scrollView.emptyViewConfig = self;
}

- (void)setHidden:(BOOL)hidden {
    _hidden = hidden;
    if (self.isNormalView) {
        self.scrollView.hidden = _hidden;
    }
}

#pragma mark - Table View Delegate & Data Source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 0;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    return cell;
}


#pragma mark - Empty Data Set Source & Delegate

//The image for the empty state
- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView {
    
    //没加载过直接显示空
    if (!self.isLoaded) {
        if (self.alwaysShowEmptyView) {
            return self.image ? : [UIImage imageNamed:@"empty_empty"];
        }
        return nil;
        
    }
    
    if (self.isLoading) {
        
         NSString *filePath = [[NSBundle mainBundle] pathForResource:@"empty_loading" ofType:@"gif"];
        
        NSData *data = [NSData dataWithContentsOfFile:filePath];
        
        UIImage *image = [UIImage sd_animatedGIFWithData:data];//实现gif图的展示
        
        return self.loadingImage ? : image;
    }
    
    return self.image ? : [UIImage imageNamed:@"empty_empty"];
}

//The attributed string for the title of the empty state:

- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView {
    
    
    
    NSString *text = nil;
    
    if (!self.isLoaded) {
        if (self.alwaysShowEmptyView) {
            text = self.message ? : @"暂无数据";
        } else {
            text = @"";
        }
    } else if (self.isLoading) {
        text = self.loadingMessage ? : @"";
    } else {
        text = self.message ? : @"暂无数据";
    }
    
    
    
    NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:16.0f],
                                 NSForegroundColorAttributeName: [UIColor darkGrayColor]};
    
    return [[NSAttributedString alloc] initWithString:text attributes:attributes];
}

//The background color for the empty state:

- (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView {
    return [UIColor clearColor];
}

//Asks for scrolling permission (Default is NO) :

- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView {
    return !self.isNormalView;
}

/**
 Tells the delegate that the empty data set did appear.
 
 @param scrollView A scrollView subclass informing the delegate.
 */
- (void)emptyDataSetDidAppear:(UIScrollView *)scrollView {
    if ([scrollView isKindOfClass:[UITableView class]]) {
        UITableView *tableView = (UITableView *)scrollView;
        UIView *view = [tableView valueForKey:@"emptyDataSetView"];
        
        
        CGFloat height = tableView.tableFooterView.frame.size.height + tableView.tableHeaderView.frame.size.height;
        
        
        //UIView *bottomView = tableView.tableFooterView ? : tableView.tableHeaderView;
        
        //CGFloat height = CGRectGetMaxY(bottomView.frame);
        
        CGFloat offset = 0;
        
//        if (self.scrollView.mj_header.state == MJRefreshStateRefreshing) {
//            offset = MJRefreshHeaderHeight;
//        }
        
        if (scrollView.bounds.origin.y < height) {
            CGRect frame = view.frame;
            //向下偏移
            frame.origin.y = height - offset;
            //适配大小
            if (tableView.frame.size.height + tableView.contentOffset.y > height + kEmptyViewMinHeight) {
                frame.size.height = tableView.frame.size.height + tableView.contentOffset.y - height + offset;
            } else {
                frame.size.height = kEmptyViewMinHeight;
                
            }
            view.frame = frame;
        } else {
            CGRect frame = view.frame;
            frame.origin.y = 0;
            frame.size.height = CGRectGetHeight(tableView.frame);
            view.frame = frame;
        }
    }
    
}

/*
//The attributed string for the description of the empty state:

- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView
{
    NSString *text = @"This allows you to share photos from your library and save photos to your camera roll.";
    
    NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];
    paragraph.lineBreakMode = NSLineBreakByWordWrapping;
    paragraph.alignment = NSTextAlignmentCenter;
    
    NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f],
                                 NSForegroundColorAttributeName: [UIColor lightGrayColor],
                                 NSParagraphStyleAttributeName: paragraph};
    
    return [[NSAttributedString alloc] initWithString:text attributes:attributes];
}
//The attributed string to be used for the specified button state:

- (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state
{
    NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0f]};
    
    return [[NSAttributedString alloc] initWithString:@"Continue" attributes:attributes];
}
//or the image to be used for the specified button state:

- (UIImage *)buttonImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state
{
    return [UIImage imageNamed:@"button_image"];
}

*/




/*
//If you need a more complex layout, you can return a custom view instead:

- (UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView
{
    UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [activityView startAnimating];
    return activityView;
}


//The image view animation

- (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"transform"];
    
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0)];
    
    animation.duration = 0.25;
    animation.cumulative = YES;
    animation.repeatCount = MAXFLOAT;
    
    return animation;
}
 
*/

/* EmptyView的frame为scrollView.bounds, 此处只是下移EmptyView里面的视图
//Additionally, you can also adjust the vertical alignment of the content view (ie: useful when there is tableHeaderView visible):

- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView {
    if ([scrollView isKindOfClass:[UITableView class]]) {
        UITableView *tableView = (UITableView *)scrollView;
        //return 0;
        return tableView.tableHeaderView.frame.size.height / 2 + tableView.tableFooterView.frame.size.height;
    }
    return 0;
    
}
 
 */
 

//Finally, you can separate components from each other (default separation is 11 pts):
/*
- (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView
{
    return 0.0f;
}
 */
//Delegate Implementation

//Return the behaviours you would expect from the empty states, and receive the user events.

//Asks to know if the empty state should be rendered and displayed (Default is YES) :

/*

- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView
{
    return YES;
}
//Asks for interaction permission (Default is YES) :

- (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView
{
    return YES;
}
//Asks for scrolling permission (Default is NO) :

- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView
{
    return YES;
}
//Asks for image view animation permission (Default is NO) :

- (BOOL) emptyDataSetShouldAllowImageViewAnimate:(UIScrollView *)scrollView
{
    return YES;
}
//Notifies when the dataset view was tapped:

- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view
{
    // Do something
}
//Notifies when the data set call to action button was tapped:

- (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button
{
    // Do something
}
 
*/


@end

@implementation UIScrollView (LKEmptyViewConfig)

- (void)setEmptyViewConfig:(LKEmptyViewConfig *)emptyViewConfig {
    objc_setAssociatedObject(self, @selector(emptyViewConfig), emptyViewConfig, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (LKEmptyViewConfig *)emptyViewConfig {
    return objc_getAssociatedObject(self, _cmd);
}



@end

